Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FETCH .. WITH TIES issue detection #2111

Merged
merged 23 commits into from
Dec 30, 2024
Merged

Conversation

makalaaneesh
Copy link
Collaborator

@makalaaneesh makalaaneesh commented Dec 23, 2024

Describe the changes in this pull request

https://yugabyte.atlassian.net/browse/DB-14221

  • Added issue for FETCH .. WITH TIES via SelectStmtDetector
image

Describe if there are any user-facing changes

How was this pull request tested?

  • Unit tests
  • Assessment Tests
  • Analyze Schema tests

Does your PR have changes that can cause upgrade issues?

Component Breaking changes?
MetaDB Yes/No
Name registry json Yes/No
Data File Descriptor Json Yes/No
Export Snapshot Status Json Yes/No
Import Data State Yes/No
Export Status Json Yes/No
Data .sql files of tables Yes/No
Export and import data queue Yes/No
Schema Dump Yes/No
AssessmentDB Yes/No
Sizing DB Yes/No
Migration Assessment Report Json Yes/No
Callhome Json Yes/No
YugabyteD Tables Yes/No
TargetDB Metadata Tables Yes/No

@makalaaneesh makalaaneesh requested review from sanyamsinghal and priyanshi-yb and removed request for sanyamsinghal December 24, 2024 05:59
@makalaaneesh makalaaneesh marked this pull request as ready for review December 24, 2024 06:00
@@ -214,6 +214,7 @@ const (
BEFORE_FOR_EACH_ROW_TRIGGERS_ON_PARTITIONED_TABLE_FEATURE = "BEFORE ROW triggers on Partitioned tables"
PK_UK_CONSTRAINT_ON_COMPLEX_DATATYPES_FEATURE = "Primary / Unique key constraints on complex datatypes"
REGEX_FUNCTIONS_FEATURE = "Regex Functions"
FETCH_WITH_TIES_FEATURE = "FETCH .. WITH TIES"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe "FETCH .. WITH TIES Clause"?

Comment on lines 214 to 221
func (d *SelectStmtDetector) getSelectStmtFromProto(msg protoreflect.Message) (*pg_query.SelectStmt, error) {
protoMsg := msg.Interface().(proto.Message)
selectStmtNode, ok := protoMsg.(*pg_query.SelectStmt)
if !ok {
return nil, fmt.Errorf("failed to cast %s to %s", queryparser.PG_QUERY_SELECTSTMT_NODE, queryparser.PG_QUERY_SELECTSTMT_NODE)
}
return selectStmtNode, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets add this function inhelper_protomsg.go

}
// checks if a SelectStmt node uses a FETCH clause with TIES
// https://www.postgresql.org/docs/13/sql-select.html#SQL-LIMIT
if selectStmtNode.LimitOption == pg_query.LimitOption_LIMIT_OPTION_WITH_TIES {
Copy link
Contributor

@priyanshi-yb priyanshi-yb Dec 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

define this limit option const pg_query.LimitOption_LIMIT_OPTION_WITH_TIES in queryparser
After these two changes (this and the above one), you won't need to use the pg_query package. Because we already have queryparser pkg for parser related stuff. So I think we should not use the pg_query directly here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Don't think we can completely avoid this because the return type would be a pg_query.SelectStmt. But we probably don't need to have an explicit dependency.

But broadly speaking, agree with not preferring to use pg_query directly here. (as much as possilble).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, as much as possible we should avoid using it directly in the queryissue.

Comment on lines 223 to 236
func (d *SelectStmtDetector) Detect(msg protoreflect.Message) error {
if queryparser.GetMsgFullName(msg) == queryparser.PG_QUERY_SELECTSTMT_NODE {
selectStmtNode, err := d.getSelectStmtFromProto(msg)
if err != nil {
return err
}
// checks if a SelectStmt node uses a FETCH clause with TIES
// https://www.postgresql.org/docs/13/sql-select.html#SQL-LIMIT
if selectStmtNode.LimitOption == pg_query.LimitOption_LIMIT_OPTION_WITH_TIES {
d.limitOptionWithTiesDetected = true
}
}
return nil
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking can we stick to one of the approaches (protomsg) as a primary approach, and use other one where its significantly making things easy, other code might become a bit messy.
There is a overhead of conversion also comes.

Here in this case i guess something like GetStringField() or GetEnumField() we already have, can be used to get pg_query.LimitOption_LIMIT_OPTION_WITH_TIES

Copy link
Collaborator Author

@makalaaneesh makalaaneesh Dec 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point about consistency. But why, in general, do you prefer accessing fields of a message via protoreflect.Message rather than structs directly?

There is a overhead of conversion also comes.

I doubt there is significant overhead. It's just type assertion.

Copy link
Collaborator Author

@makalaaneesh makalaaneesh Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged this for now, since it's been pending for a while and I had to resolve a lot of conflicts!
But let's discuss this nonetheless.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why, in general, do you prefer accessing fields of a message via protoreflect.Message rather than structs directly?

@makalaaneesh
Couple of reasons:
The field name we use to fetch from the protomsg is exactly the same as visible in a parse tree output.
In case of structs, you need to figureout the struct field which gives you the required info(sligtly different named)

Consistency here is another reason.

@@ -515,3 +515,65 @@ func TestRegexFunctionsIssue(t *testing.T) {
}

}

func TestWithTies(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: TestFetchWithTiesInSelect ?

Copy link
Contributor

@priyanshi-yb priyanshi-yb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@makalaaneesh makalaaneesh merged commit fa542b7 into main Dec 30, 2024
67 checks passed
@makalaaneesh makalaaneesh deleted the aneesh/fetch-with-ties-issue branch December 30, 2024 04:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants